﻿using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Scripting;
using Microsoft.Scripting.Ast;
using Microsoft.Linq.Expressions;

namespace DlrBasic.Parser.Ast
{
    class Print : Statement
    {
        DlrBasicExpression[] expressions;
        bool newLine;
        DlrBasicExpression usingFormat;

        // in expressions use null for tab (next zone)
        public Print(SourceSpan span, DlrBasicExpression[] expressions, bool newLine, DlrBasicExpression usingFormat)
            : base(span)
        {
            this.expressions = expressions;
            this.newLine = newLine;
            this.usingFormat = usingFormat;
        }

        protected internal override Expression Generate(DlrBasicGenerator generator, StateMemberGenerator stateParameter, LambdaBuilder builder)
        {
            List<Expression> printExpressions = new List<Expression>();

            if (usingFormat == null)
            {
                foreach (DlrBasicExpression expr in expressions)
                {
                    if (expr == null)
                    {
                        Expression print = Utils.Call(typeof(DlrBasicHelpers).GetMethod("PrintTab"),
                            SourceSpan.None, Utils.CodeContext());
                        printExpressions.Add(print);
                    }
                    else
                    {
                        Expression print = Utils.Call(typeof(DlrBasicHelpers).GetMethod("Print"),
                            SourceSpan, Utils.CodeContext(), Expression.ConvertHelper(expr.Generate(generator), typeof(Object)));
                        printExpressions.Add(print);
                    }
                }
            }
            else
            {
                Expression[] arguments = new Expression[expressions.Length];
                for (int i = 0; i < arguments.Length; i++)
                {
                    arguments[i] = Expression.ConvertHelper(expressions[i].Generate(generator), typeof(object));
                }
                Expression argumentsArray = Expression.NewArrayHelper(typeof(object), arguments);

                Expression format = TypeConversionUtils.BuildConversionTo(typeof(string),
                    usingFormat.Generate(generator));

                Expression print = Utils.Call(typeof(DlrBasicHelpers).GetMethod("PrintFormatted"),
                            SourceSpan, Utils.CodeContext(), 
                            format, argumentsArray);
                printExpressions.Add(print);
            }

            if (newLine)
            {
                Expression print = Utils.Call(typeof(DlrBasicHelpers).GetMethod("PrintLine"),
                    new SourceSpan(SourceSpan.End, SourceSpan.End), Utils.CodeContext());
                printExpressions.Add(print);
            }

            printExpressions.Add(base.Generate(generator, stateParameter, builder));
            return Utils.Block(SourceSpan, printExpressions.ToArray());
        }

    }
}
